package com.wt.wechatTools;

import android.Manifest;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.wt.wechatTools.adapter.AdapterContacts;
import com.wt.wechatTools.room.entity.ContactsEntity;
import com.wt.wechatTools.room.entity.UserEntity;
import com.wt.wechatTools.tools.AlertDialogLoading;
import com.wt.wechatTools.tools.MyRequest;
import com.wt.wechatTools.view_model.ContactsViewModel;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * A simple {@link Fragment} subclass.
 * create an instance of this fragment.
 */
public class FragmentContacts extends Fragment {
    private static final String TAG = "FragmentContacts";
    private RecyclerView recyclerView;
    private Button btnUpdate;
    private ContactsViewModel contactsViewModel;
    private AdapterContacts adapterContacts;
    private Spinner spinner;
    private List<String> spinnerList = new ArrayList<String>();
    private ArrayAdapter<String> spinerAdapter;
    private Button btnGetContacts;
    private AlertDialogLoading alertDialogLoading;
    private NavController nv;
    private AlertDialog alertDialog;
    private UserEntity userEntityRoot;
    private List<ContactsEntity> cl = new ArrayList<>();

    public FragmentContacts() {
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        contactsViewModel = new ViewModelProvider(getActivity()).get(ContactsViewModel.class);
        View viewHome = inflater.inflate(R.layout.fragment_contacts, container, false);
        btnUpdate = viewHome.findViewById(R.id.btnUpdate);

        //RecyclerView
        recyclerView = viewHome.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        adapterContacts = new AdapterContacts(getContext());
        recyclerView.setAdapter(adapterContacts);

        //获取用户信息
        contactsViewModel.getUserLive().observe(getActivity(), new Observer<UserEntity>() {
            @Override
            public void onChanged(UserEntity userEntity) {
                userEntityRoot = userEntity;
                if (userEntity != null) {
                    switch (userEntity.getRole()) {
                        case 1:
                            btnUpdate.setVisibility(View.GONE);
                            break;
                        case 2:
                            btnUpdate.setVisibility(View.VISIBLE);
                    }
                }
            }
        });

        //获取本机通讯录
        btnGetContacts = viewHome.findViewById(R.id.btnGetContacts);
        btnGetContacts.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //提示用户给予通讯录权限
                if (ContextCompat.checkSelfPermission(view.getContext(), Manifest.permission.READ_CONTACTS)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(
                            getActivity(), new String[]{Manifest.permission.READ_CONTACTS}, 1);
                } else {
                    getAllContacts(view);
                }
            }
        });

        //------------------------------dialog
        //loading
        View dialogView = getLayoutInflater().inflate(R.layout.myloadingview, null);
        alertDialogLoading = new AlertDialogLoading(getContext(), dialogView);

        //提示框
        alertDialog = new AlertDialog.Builder(getContext()).create();
        alertDialog.setTitle("提示");
        alertDialog.setMessage("即将跳转至登录页面！");
        alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //跳转至登录页
                nv.navigate(R.id.fragmentLogin);
            }
        });

        alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        //更新名单
        viewHome.findViewById(R.id.btnUpdate).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                nv = Navigation.findNavController(view);
                //Handler
                MyHandler myHandler = new MyHandler(nv, alertDialogLoading);
                //获取token username
                String username = userEntityRoot.getUserName();
                String token = userEntityRoot.getToken();
                String dataSource = userEntityRoot.getDataSource();
                if (username.isEmpty() || token.isEmpty()) {
                    //提示用户登录
                    alertDialog.show();
                    return;
                }

                //https://www.runoob.com/w3cnote/android-tutorial-handler-message.html
                //创建线程
                new Thread() {
                    public void run() {
                        //任务开始 显示loading
                        Message msgLoading = new Message();
                        msgLoading.what = 3;
                        myHandler.sendMessage(msgLoading);
                        //判断本地是否有通讯录
                        List<ContactsEntity> cl = contactsViewModel.getAllContacts();
                        if (cl.size() == 0) {
                            //组装参数
                            RequestBody requestBody = new FormBody.Builder()
                                    .add("username", username)
                                    .add("token", token)
                                    .add("dataSource", dataSource)
                                    .build();
                            UpdateContactsList(requestBody, myHandler, true);
                        } else {
                            //组装参数-获取名单
                            RequestBody requestBody = new FormBody.Builder()
                                    .add("username", username)
                                    .add("token", token)
                                    .add("dataSource", dataSource)
                                    .add("isUpdate", "true")
                                    .build();
                            UpdateContactsList(requestBody, myHandler, false);
                            //组装参数-同步数据
                            List<ContactsEntity> upList = contactsViewModel.getContacts();
                            if (upList.size() > 0) {
                                RequestBody requestBodyUpdate = new FormBody.Builder()
                                        .add("phoneList", JSON.toJSONString(upList))
                                        .add("username", username)
                                        .add("token", token)
                                        .build();
                                pushContactsList(requestBodyUpdate);
                            }
                        }
                    }
                }.start();
            }
        });

        //下拉列表 Spinner
        //http://c.biancheng.net/view/3006.html
        //https://blog.csdn.net/q4878802/article/details/50775002
        // 第一步：定义下拉列表内容
        spinnerList.add("请选择类型");//等于1为"未使用"
        spinnerList.add("未使用");//等于1为"未使用"
        spinnerList.add("任务清单");//等于5为 "任务清单"
        spinnerList.add("最近任务");//tastBatch任务批次为最大的数据
        spinnerList.add("执行成功");//等于2为"执行成功"
        spinnerList.add("执行失败");//等于3为"执行失败"
        spinnerList.add("添加成功");//等于4为 "添加成功"
        spinner = viewHome.findViewById(R.id.spinnerType);

        //第二步：为下拉列表定义一个适配器
        spinerAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, spinnerList);
        //第三步：设置下拉列表下拉时的菜单样式
        spinerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        //第四步：将适配器添加到下拉列表上
        spinner.setAdapter(spinerAdapter);
        //第五步：添加监听器，为下拉列表设置事件的响应
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //parent.setVisibility(View.VISIBLE);
                switch (spinerAdapter.getItem(position)) {
                    case "执行成功":
                        getContactsByStateThred(2);
                        break;
                    case "执行失败":
                        getContactsByStateThred(3);
                        break;
                    case "未使用":
                        getContactsByStateThred(1);
                        break;
                    case "最近任务":
                        cl = new ArrayList<>();
                        //显示tastBatch 最大的数据  userEntityRoot
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                cl = contactsViewModel.getContactsByTastBatch(userEntityRoot.getTaskBatch());
                                new Handler(Looper.getMainLooper()).post(new Runnable() {
                                    @Override
                                    public void run() {
                                        adapterContacts.setContactsEntities(cl);
                                        adapterContacts.notifyDataSetChanged();
                                    }
                                });
                            }
                        }).start();
                        break;
                    case "任务清单":
                        getContactsByStateThred(5);
                        break;
                    case "添加成功":
                        getContactsByStateThred(4);
                        break;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        return viewHome;
    }

    private void pushContactsList(RequestBody requestBodyUpdate) {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(MyRequest.proUrl + "updateUserCustomerList")
                .post(requestBodyUpdate)
                //增加关闭连接，不让它保持连接。           https://blog.csdn.net/zhangteng22/article/details/52233126
                .addHeader("Connection", "close")
                .build();
        Response res = null;
        try {
            res = okHttpClient.newCall(request).execute();
            String result = res.body().string();
            if (res.isSuccessful()) {
                Looper.prepare();
                Toast.makeText(getContext(), "同步数据成功！", Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 根据状态 筛选名单数据
     *
     * @param i
     */
    private void getContactsByStateThred(int i) {
        cl = new ArrayList<>();
        //绑定数据,当数据发生变化时也会更新
        new Thread(new Runnable() {
            @Override
            public void run() {
                cl = contactsViewModel.getContactsByState(i);
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        adapterContacts.setContactsEntities(cl);
                        adapterContacts.notifyDataSetChanged();
                    }
                });
            }
        }).start();
    }

    /**
     * 更新本地名单
     *
     * @param requestBody
     * @param myHandler
     * @param isFirst     第一次 true   以后都是false
     */
    private void UpdateContactsList(RequestBody requestBody, MyHandler myHandler, boolean isFirst) {
        //如果用户本地sqlite数据库中有数据那么就是请求更新数据。流程为：服务端随机返回未知数量的数据。客户端将从未得到过的数据，添加至sqlite数据库。
        OkHttpClient okHttpClient = new OkHttpClient();

        Request request = new Request.Builder()
                .url(MyRequest.proUrl + "getCustomerList")
                .post(requestBody)
                //增加关闭连接，不让它保持连接。           https://blog.csdn.net/zhangteng22/article/details/52233126
                .addHeader("Connection", "close")
                .build();
        Response res = null;
        try {
            res = okHttpClient.newCall(request).execute();
            String result = res.body().string();
            if (res.isSuccessful()) {
                //序列化 https://www.runoob.com/w3cnote/android-tutorial-json.html
                List<ContactsEntity> cnListTemp = new ArrayList<>();
                JSONArray jsonArray = new JSONArray(result);
                Integer updateCount = 0;
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                    int id = Integer.parseInt(jsonObject.getString("pk"));
                    String cellphone = jsonObject.getJSONObject("fields").getString("cellphone");
                    ContactsEntity cnTemp = new ContactsEntity(id, null, cellphone, 1, 1);
                    //第一次
                    if (isFirst) {
                        cnListTemp.add(cnTemp);
                        continue;
                    }
                    //第一次以后
                    //判断本地数据库中是否存在此手机号
                    if (contactsViewModel.getContactsByCellPhone(cellphone) == null) {
                        updateCount++;
                        //加入本地数据库
                        contactsViewModel.insert(cnTemp);
                    }
                }
                //第一次
                if (isFirst) {
                    //操作数据库
                    contactsViewModel.insertList(cnListTemp);
                    updateCount = cnListTemp.size();
                }
                //任务正常结束
                Message msgOK = new Message();
                msgOK.obj = updateCount;
                msgOK.what = 2;
                myHandler.sendMessage(msgOK);
            } else if (res.code() == 401) {
                //token过期了
                Message msgToken = new Message();
                msgToken.obj = "需要重新登录！";
                msgToken.what = 4;
                myHandler.sendMessage(msgToken);
            } else {
                Message msgServerError = new Message();
                msgServerError.obj = "服务端错误，请联系管理员！";
                msgServerError.what = 1;
                myHandler.sendMessage(msgServerError);
            }
        } catch (Exception e) {
            Message msgServerError = new Message();
            msgServerError.obj = "服务端错误，请联系管理员！";
            msgServerError.what = 1;
            myHandler.sendMessage(msgServerError);
            e.printStackTrace();
        } finally {
            res.close();
        }
    }

    //异步的方法
//    https://www.runoob.com/w3cnote/android-tutorial-handler-message.html
//    https://blog.csdn.net/qq_41673194/article/details/80022875
    private class MyHandler extends Handler {
        private NavController nv;
        private AlertDialogLoading alertDialogLoading;

        public MyHandler(NavController nv, AlertDialogLoading alertDialogLoading) {
            this.nv = nv;
            this.alertDialogLoading = alertDialogLoading;
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            Log.d(TAG, "handleMessage: " + msg);
            switch (msg.what) {
                case 1: //服务端 错误
                    alertDialogLoading.dismissLoadingDialog(); //关闭loading
                    Toast.makeText(getContext(), msg.obj.toString(), Toast.LENGTH_SHORT).show();
                    //跳转至登录页
                    break;
                case 2: //任务正常结束
                    alertDialogLoading.dismissLoadingDialog(); //关闭loading
                    Toast.makeText(getContext(), "成功更新了" + msg.obj + "条数据！", Toast.LENGTH_SHORT).show();
                    break;
                case 3: //任务开始，显示loading
                    alertDialogLoading.showLoadingDialog();
                    break;
                case 4: //token过期了需要重新登录
                    alertDialogLoading.dismissLoadingDialog(); //关闭loading
                    //跳转至登录页
                    nv.navigate(R.id.fragmentLogin);
                    break;
            }
        }
    }

    /**
     * 获取手机联系人 参考：https://blog.csdn.net/ccccdddxxx/article/details/7038533
     */
    public void getAllContacts(View view) {
        //判断用户是否已经授权给我们了 如果没有，调用下面方法向用户申请授权，之后系统就会弹出一个权限申请的对话框
        if (ContextCompat.checkSelfPermission(view.getContext(), Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getContext(), "请给予通讯录权限！", Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            ContentResolver contentResolver = this.getContext().getContentResolver();
            //查询数据，返回Cursor
            Cursor cursor = contentResolver.query(uri, null, null, null, null);
            List<ContactsEntity> contactsEntityLis = new ArrayList<>();
            String phoneNumber = "";
            while (cursor.moveToNext()) {
                //获取联系人的ID
                String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                //获取联系人的姓名
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                //构造联系人信息
                //查询电话类型的数据操作
                Cursor phones = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
                while (phones.moveToNext()) {
                    phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    //添加Phone的信息
                }
                phones.close();
                if (!phoneNumber.isEmpty()) {
                    contactsEntityLis.add(new ContactsEntity(null, name, replaceBlank(phoneNumber), 1, null));
                }

            }
            cursor.close();

            if (contactsEntityLis.size() == 0) {
                Toast.makeText(getContext(), "没有读取到本地通讯录！", Toast.LENGTH_SHORT).show();
                return;
            }

            //保存数据
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Integer ct = 0;
                    for (ContactsEntity cn : contactsEntityLis) {
                        //判断本地数据库中是否存在此手机号
                        if (contactsViewModel.getContactsByCellPhone(cn.getCellPhone()) == null) {
                            Log.d(TAG, "run: insert " + cn.getCellPhone());
                            //加入本地数据库
                            contactsViewModel.insert(cn);
                            ct++;
                        } else {
                            Log.d(TAG, "run: 重复 " + cn.getCellPhone());
                        }
                    }
                    Looper.prepare();
                    Toast.makeText(getContext(), "成功更新了，" + ct + "条数据！", Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            }).start();
        } catch (Exception e) {
            Log.d(TAG, "getAllContacts: " + e);
        }
    }

    /**
     * 清除字符串中的空值
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }
}